using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;


namespace BloodBot
{
    public class HUD : Microsoft.Xna.Framework.GameComponent
    {

        SpriteFont font;
        SpriteBatch spriteBatch;

        Color HudColor = Color.LightGray;
        Vector2 HudVec = new Vector2(10, 10);
        Vector2 healthBarVec;
        Vector2 enemiesLeftVec;
        Vector2 levelTimerVec;

        int enemiesRemaining;
        Texture2D healthBar;

        Texture2D crosshairLine;
        Texture2D damageOverlay;
        Rectangle damageRectangle;

        int crosshairOuterSize = 10;
        int crosshairInnerSize = 3;
        float crosshairWidth = 1.0f;
        Color crosshairColor = Color.White;

        List<Enemy> enemyModel;
        Player player;

        Stopwatch levelTimer;
        

        public HUD(Game game, List<Enemy> enemyModel, Player player,Stopwatch levelTimer, SpriteBatch spriteBatch, SpriteFont font)
            : base(game)
        {
            this.player = player;
            this.enemyModel = enemyModel;
            this.spriteBatch = spriteBatch;
            this.font = font;
            this.levelTimer = levelTimer;
        }

        public override void Initialize()
        {
            healthBar = Game.Content.Load<Texture2D>(@"HealthBar");
            crosshairLine = new Texture2D(Game.GraphicsDevice, 1, 1, false, SurfaceFormat.Color);
            crosshairLine.SetData(new[] { Color.White });
            healthBarVec = new Vector2(20, 20);
            enemiesLeftVec = new Vector2(Game.GraphicsDevice.Viewport.Width - 200, 10);
            levelTimerVec = new Vector2(Game.GraphicsDevice.Viewport.Width - 120, 40);
            enemiesRemaining = 1;
            damageOverlay = new Texture2D(Game.GraphicsDevice, 1, 1);
            damageOverlay.SetData(new Color[] { Color.Red });
            damageRectangle = new Rectangle(0, 0, Game.Window.ClientBounds.Width, Game.Window.ClientBounds.Height);
            base.Initialize();
        }


        public override void Update(GameTime gameTime)
        {
            //Not used yet, but maybe if HUD textures change or we impliment hud interactivity, this is where it'll happen
            
            base.Update(gameTime);
        }

        public void SetEnemiesRemaining(int rem)
        {
            enemiesRemaining = rem;
        }

        public void Draw()
        {
            
            spriteBatch.Begin();
            
            //Debug(spriteBatch);
            //Draw damage overlay
            Color damageColor = Color.Red;
            if (player.losingHealth)
            {
                float time = player.damageTimer.Elapsed.Milliseconds;

                // the alphavalue here starts it from a max of 200 - any higher and it turns the screen solid red
                float alphaValue = 200 - (time / 2000f * 255);
                
                damageColor.A = (byte)alphaValue;
                damageColor.R = (byte)alphaValue;
                Color tempColor = Color.Transparent;
                damageOverlay.SetData(new[] { damageColor });
                spriteBatch.Draw(damageOverlay, damageRectangle, damageColor);
            }

            //Draw the elapsed level time
            DrawText(levelTimer.Elapsed.ToString(@"mm\:ss"), levelTimerVec, HudColor);

            //Draw the enemies remaining
            DrawText("Cells Left:", enemiesLeftVec, Color.Red);
            DrawText(enemiesRemaining.ToString(), new Vector2( enemiesLeftVec.X + 150, enemiesLeftVec.Y), HudColor);

            DrawHealthBar(spriteBatch);
            
            DrawCrosshair(spriteBatch);

            spriteBatch.End();

        }

        private void DrawHealthBar(SpriteBatch spriteBatch)
        {
            //Draw the Negative Space for the health bar
            spriteBatch.Draw(healthBar, new Rectangle((int)healthBarVec.X,
                 (int)healthBarVec.Y, healthBar.Width, 20), new Rectangle(0, 45, healthBar.Width, 44), Color.Gray);

            //Draw the health for the health bar
            spriteBatch.Draw(healthBar, new Rectangle((int)healthBarVec.X,
                (int)healthBarVec.Y, (int)(healthBar.Width * ((double)player.currentHealth / 100)), 20), new Rectangle(0, 45, healthBar.Width, 44), Color.Red);

            //Draw the box around the health bar
            spriteBatch.Draw(healthBar, new Rectangle((int)healthBarVec.X,
                  (int)healthBarVec.Y, healthBar.Width, 20), new Rectangle(0, 0, healthBar.Width, 44), Color.White);
        }

        private void Debug(SpriteBatch spriteBatch)
        {
            
            //if you need to debug anything, positions, values, whatever, this is the place. just do a new DrawText.
            int x = 10;
            DrawText("Player health = " + player.currentHealth.ToString() + " Try pressing arrows up and down", new Vector2(HudVec.X, HudVec.Y + x), HudColor);

            foreach (Enemy enemy in enemyModel)
            {
                x += 10;
                DrawText("EnemyID = " + enemy.indexNo.ToString() +
                    " Health = " + enemy.health.ToString() +
                    " pos = " + enemy.position.ToString()
                    , new Vector2(HudVec.X, HudVec.Y + x), HudColor);
            }
        }

        private void DrawText(String text, Vector2 textVec, Color c)
        {
            spriteBatch.DrawString(font, text, textVec, c);
        }

        void DrawLine(SpriteBatch batch, Texture2D blank, float width, Color color, Vector2 point1, Vector2 point2)
        {
            float angle = (float)Math.Atan2(point2.Y - point1.Y, point2.X - point1.X);
            float length = Vector2.Distance(point1, point2);

            batch.Draw(blank, point1, null, color,
                       angle, Vector2.Zero, new Vector2(length, width),
                       SpriteEffects.None, 0);
        }

        private void DrawCrosshair(SpriteBatch spriteBatch)
        {
            //Drawing the crosshair, 4 lines total with a break in the very center
            DrawLine(spriteBatch, crosshairLine, crosshairWidth, crosshairColor,
                new Vector2(Game.GraphicsDevice.Viewport.Width / 2, (Game.GraphicsDevice.Viewport.Height / 2 - crosshairOuterSize)),
                new Vector2(Game.GraphicsDevice.Viewport.Width / 2, (Game.GraphicsDevice.Viewport.Height / 2 - crosshairInnerSize)));
            DrawLine(spriteBatch, crosshairLine, crosshairWidth, crosshairColor,
                new Vector2(Game.GraphicsDevice.Viewport.Width / 2, (Game.GraphicsDevice.Viewport.Height / 2 + crosshairInnerSize+1)),
                new Vector2(Game.GraphicsDevice.Viewport.Width / 2, (Game.GraphicsDevice.Viewport.Height / 2 + crosshairOuterSize+1)));
            DrawLine(spriteBatch, crosshairLine, crosshairWidth, crosshairColor,
                new Vector2((Game.GraphicsDevice.Viewport.Width / 2 - (crosshairOuterSize+1)), Game.GraphicsDevice.Viewport.Height / 2),
                new Vector2((Game.GraphicsDevice.Viewport.Width / 2 - (crosshairInnerSize+1)), Game.GraphicsDevice.Viewport.Height / 2));
            DrawLine(spriteBatch, crosshairLine, crosshairWidth, crosshairColor,
                new Vector2((Game.GraphicsDevice.Viewport.Width / 2 + crosshairInnerSize), Game.GraphicsDevice.Viewport.Height / 2),
                new Vector2((Game.GraphicsDevice.Viewport.Width / 2 + crosshairOuterSize), Game.GraphicsDevice.Viewport.Height / 2)); 
        }


    }  
}
